function [y, nums] = img2blocks(x, block_size, border_size)
% Mordecai Lee, 2017-11-30, Thu, 22:52:05

% if nargin == 0
%     x = imread(fullfile(srpath.getDataPath('Urban100'), 'img057.jpg'));
%     x = rgb2gray(x);
%     %%
%     x = x(1:57, 1:60);
%     scale = 4;
%     y = srimg.im2lr(x, scale, 'Bicubic', 'I');
%     
%     w = FSRCNN.deploy(single(y), scale);
%     srimg.psnr(x, w(1:end-3, :), scale)
%     srimg.psnr(x, w(2:end-2, :), scale)
%     srimg.psnr(x, w(3:end-1, :), scale)
%     srimg.psnr(x, w(4:end, :), scale)
%     
%     %%
%     block_size = 20;  border_size = 3;
%     b = srimg.img2blocks(y, block_size, border_size);
%     z = srimg.blocks2img(b, size(y), border_size);
%     
%     % sum(double(y(:)) - double(z(:)))
% end
% 
% if nargin == 0
%     DataPath = srpath.getDataPath('Urban100');
%     imgs = srimg.dirimgs(DataPath, true);
%     block_size = 100;  border_size = 5;
%     for i = 1 : length(imgs)
%         x = imread(fullfile(DataPath, imgs{i}));
%         if ndims(x) == 3
%             x = rgb2gray(x);
%         end
%         
%         b = srimg.img2blocks(x, block_size, border_size);
%         y = srimg.blocks2img(b, size(x), border_size);
%         if sum(double(x(:)) - double(y(:))) ~= 0
%             warning('Image %s: Error!', imgs{i})
%         end
%     end
%     y = 0;
%     return
% end

if iscell(x)
    s = cellfun(@size, x, 'UniformOutput', false);
    s = min(cat(1, s{:}));
    bool = block_size > s;
    block_size(bool) = s(bool);
    
    [y, nums] = cellfun(@(X) srimg.img2blocks(X, block_size, border_size), x, 'UniformOutput', false);
    y = cat(3, y{:}); nums = [nums{:}];
    return
end

if length(block_size) == 1, block_size = block_size([1 1]); end
if length(border_size) == 1, border_size = border_size([1 1]); end
border_size = 2 * border_size;

x_size = size(x);
bool = x_size < block_size;
block_size(bool) = x_size(bool);

block_num = ceil((x_size-block_size) ./ (block_size - border_size)) + 1;

CC = zeros(block_num(2), 2);
cc = [0 border_size(2)];
for ci = 1 : block_num(2)
    cc(2) = cc(2) - border_size(2);
    cc = [cc(2)+1, cc(2)+block_size(2)];
    if cc(2) > x_size(2)
        cc = cc - (cc(2) - x_size(2));
    end
    CC(ci, :) = cc;
    % disp(cc)
end

cnt = 0;
y = zeros([block_size prod(block_num)]);

rr = [0 border_size(1)];
for ri = 1 : block_num(1)
    rr(2) = rr(2) - border_size(1);
    rr = [rr(2)+1, rr(2)+block_size(1)];
    if rr(2) > x_size(1)
        rr = rr - (rr(2) - x_size(1));
    end
    % disp(rr)
    
    for ci = 1 : block_num(2)
        cnt = cnt + 1;
        y(:, :, cnt) = x(rr(1) : rr(2), CC(ci, 1) : CC(ci, 2));
    end
end
nums = size(y, 3);

% cnt = 0;  rr = 2*border_size(1);
% for ri = 1 : block_num(1)
%     rr(end) = rr(end) - 2*border_size(1);
%     rr = rr(end)+1 : rr(end)+block_size(1);
%     if rr(end) > X_size(1)
%         rr = rr - (rr(end) - X_size(1));
%     end
%     % disp(rr([1 end]))
%     
%     cc = 2*border_size(2);
%     for ci = 1 : block_num(2)
%         cnt = cnt + 1;
%         cc(end) = cc(end) - 2*border_size(2);
%         cc = cc(end)+1 : cc(end)+block_size(2);
%         if cc(end) > X_size(2)
%             cc = cc - (cc(end) - X_size(2));
%         end
%         % disp(cc([1 end]))
%         Y(:, :, cnt) = X(rr, cc);
%     end
% end
